package org.mili.ticketeer.dao;

import org.mili.ticketeer.dao.query.v2.QueryBuilder;
import org.mili.ticketeer.dto.*;
import org.mili.ticketeer.util.Lambda;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Collections;
import java.util.List;

public class TicketDao extends AbstractDao {

    private ContactDao contactDao = DaoFactory.getDao(ContactDao.class);

    public TicketDao() {
        super(Ticket.UniqueFields.values(), Ticket.Fields.values(), Ticket.TABLE);
    }

    public List<Ticket> getTickets() throws DaoException {
        return read(new RowTransformer<Ticket>() {
            @Override
            public Ticket transform(ResultSet resultSet) throws SQLException {
                Ticket ticket = new Ticket();
                ticket.setId(resultSet.getInt(Identifieable.Fields.ID.name()));
                ticket.setPriority(resultSet.getInt(Ticket.Fields.PRIORITY.name()));
                ticket.setGroup(resultSet.getInt(Ticket.Fields.GROUP.name()));
                ticket.setState(resultSet.getInt(Ticket.Fields.STATE.name()));
                ticket.setComment(resultSet.getString(Ticket.Fields.COMMENT.name()));
                ticket.setTitle(resultSet.getString(Ticket.Fields.TITLE.name()));
                ticket.setCompletedAt(resultSet.getTimestamp(Ticket.Fields.COMPLETEDAT.name()));
                ticket.setCreatedAt(resultSet.getTimestamp(Ticket.Fields.CREATEDAT.name()));
                return ticket;
            }
        });
    }

    public ModificationResult write(final Ticket ticket) throws DaoException {
        return createOrUpdate(ticket);
    }

    public Boolean assign(final Contact contact, final Ticket ticket) throws DaoException {
        return doInDao(new Lambda<Boolean>() {
            @Override
            public Boolean exec(Object... params) throws SQLException {
                return update("insert into `contact_ticket` (`contact`, `ticket`) values(?, ?);", contact.getId(), ticket.getId()) == 1;
            }
        });
    }

    public List<Contact> getAssignmentsFor(final Ticket ticket) throws DaoException {
        List<Integer> contacts = doInDao(new Lambda<List<Integer>>() {
            @Override
            public List<Integer> exec(Object... params) throws SQLException {
                return query(new RowTransformer() {
                    @Override
                    public Integer transform(ResultSet resultSet) throws SQLException {
                        return resultSet.getInt(ContactTicket.Fields.CONTACT.name());
                    }
                }, QueryBuilder.createQueryBuilder()
                        .select()
                        .fields(ContactTicket.Fields.CONTACT)
                        .from(ContactTicket.TABLE)
                        .where()
                        .eq(ContactTicket.Fields.TICKET, ticket.getId())
                        .build());
            }
        });
        if (contacts.size() == 0) {
            return Collections.emptyList();
        }
        return contactDao.read(
                new ContactDao.ContactRowTransformer(),
                QueryBuilder.createQueryBuilder()
                        .select()
                        .fields(Identifieable.Fields.ID, contactDao.fields)
                        .from(Contact.TABLE)
                        .where()
                        .in(Identifieable.Fields.ID, contacts)
                        .build());
    }

}
